package com.bjsxt.controller;

import com.alibaba.fastjson.JSON;
import com.bjsxt.config.geetest.GeetestLib;
import com.bjsxt.config.geetest.GeetestLibResult;
import com.bjsxt.model.GeetestCodeVo;
import com.bjsxt.model.Result;
import com.bjsxt.util.IpUtils;
import com.bjsxt.util.ServletUtils;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * description:
 * 极验验证控制层
 *
 * @author ALIENWARE <br />
 * @date 2021/9/5
 */
@RestController
@RequestMapping("/gt")
@Api(tags = "极验验证控制器")
public class GeetestController {

    /**
     * 极验验证核心类
     */
    @Autowired
    private GeetestLib geetestLib;

    /**
     * redis 客户端操作对象
     */
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 极验获取第一次数据包----注册----图片
     *
     * @param uuid 用户的唯一标识
     * @return 统一响应对象
     */
    @GetMapping("/register")
    // @PreAuthorize("hasAuthority('')")
    @ApiOperation(value = "极验获取第一次数据包----注册----图片", authorizations = {@Authorization("Authorization")})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uuid", value = "用户的唯一标识", dataType = "String", paramType = "query", example = "1")
    })
    public Result<GeetestCodeVo> register(String uuid) {
        /*
        必传参数
            digestmod 此版本sdk可支持md5、sha256、hmac-sha256，md5之外的算法需特殊配置的账号，联系极验客服
        自定义参数,可选择添加
            user_id 客户端用户的唯一标识，确定用户的唯一性；作用于提供进阶数据分析服务，可在register和validate接口传入，不传入也不影响验证服务的使用；若担心用户信息风险，可作预处理(如哈希处理)再提供到极验
            client_type 客户端类型，web：电脑上的浏览器；h5：手机上的浏览器，包括移动应用内完全内置的web_view；native：通过原生sdk植入app应用的方式；unknown：未知
            ip_address 客户端请求sdk服务器的ip地址
        */
        String digestmod = "md5";
        // 构建极验需要的数据包
        Map<String, String> paramMap = new HashMap<String, String>();
        // 设置加密类型
        paramMap.put("digestmod", digestmod);
        paramMap.put("user_id", uuid);
        paramMap.put("client_type", "web");
        paramMap.put("ip_address", IpUtils.getIpAddr(ServletUtils.getRequest()));
        // 进行值的注册
        GeetestLibResult result = geetestLib.register(digestmod, paramMap);
        // 将结果状态写到session中，此处register接口存入session，后续validate接口会取出使用
        // 注意，此demo应用的session是单机模式，格外注意分布式环境下session的应用
        redisTemplate.opsForValue().set(GeetestLib.GEETEST_SERVER_STATUS_SESSION_KEY + ':' + uuid, result.getStatus(), 3, TimeUnit.MINUTES);
        // request.getSession().setAttribute(GeetestLib.GEETEST_SERVER_STATUS_SESSION_KEY, result.getStatus());
        redisTemplate.opsForValue().set(GeetestLib.GEETEST_SERVER_USER_SESSION_KEY + ':' + uuid, uuid, 3, TimeUnit.MINUTES);
        // request.getSession().setAttribute("userId", userId);
        // 根据返回的 json 文字组装成对象返回
        GeetestCodeVo geetestCodeVo = JSON.parseObject(result.getData(), GeetestCodeVo.class);
        // 注意，不要更改返回的结构和值类型
        return Result.success(geetestCodeVo);
    }
}
